/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2015-11-24 19:05:39
 ******************************************************************************/
package cn.com.xy.sms.sdk.service.operatorservice;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

import android.content.Context;
import cn.com.xy.sms.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.entity.OperatorCmdManager;
import cn.com.xy.sms.sdk.db.entity.OperatorParseManager;
import cn.com.xy.sms.sdk.dex.DexUtil;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;
import cn.com.xy.sms.sdk.net.NewXyHttpRunnable;
import cn.com.xy.sms.sdk.net.util.ServerUtil;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;
import cn.com.xy.sms.util.SdkCallBack;

import cn.com.xy.sms.sdk.util.CallBackState;

public class OperatorService {
    /*HWWATCH-4 songzhirong 20160818 start*/
	private static boolean isNoResultAndTimeOut(JSONObject retActionJson,long updateTime){
		if(retActionJson == null) return true;
		String status = retActionJson.optString("status");
		if(!Constant.FIND_CMD_STATUS.equalsIgnoreCase(status) && System.currentTimeMillis() > updateTime + Constant.HOUR * 6){
			return true;
		}
		return false;
	}
    /*HWWATCH-4 songzhirong 20160818 end*/
    /***
     * 获取运营商指令。查询余额指令，查询流量指令
     * 
     * @param phoneNum
     *            手机号
     * @param simIccid
     *            simIccid
     * @param callBack
     *            回调，如果说本地没有则走网络查询。需要回调。
     * @return
     */
    public static JSONObject queryOperatorCmd(String phoneNum, String simIccid,
    		HashMap<String,String> extend, SdkCallBack callBack) {
        /* SDK-529 huangzhiqiang 20160711 start */
        if (StringUtils.isNull(phoneNum)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "phone num is null");
            return null;
        }
        /* SDK-529 huangzhiqiang 20160711 end */

        // 先查本地缓存，
        // 本地缓存是否过有效期，过有效期需要重新网络查询。
        // 网络查询到，持久化到缓存。    	
    	JSONObject json = OperatorCmdManager.queryOperatorCmd(phoneNum, simIccid, extend);
		if (json != null) {
			try {
				String time = json.optString(OperatorCmdManager.UPDATE_INFO_TIME);
				JSONObject retActionJson = new JSONObject(json.optString(OperatorCmdManager.ACTIONS));

				long updateTime = Long.parseLong(time);				
			    /*HWWATCH-4 songzhirong 20160818 start*/
				if(isNoResultAndTimeOut(retActionJson, updateTime) || 
						System.currentTimeMillis() > (updateTime + 
								DexUtil.getUpdateCycleByType(OnlineUpdateCycleConfigInterface.TYPE_QUERY_OPERATOR_INFO_CYCLE,Constant.month))){

					// 已过期
					int netType = XyUtil.checkNetWork(Constant.getContext());
					if (netType == -1) {// 无可用网络，因为无法查询，就返回之前的数据
						XyUtil.doXycallBackResult(callBack, "0", retActionJson);
						return retActionJson;
					} else {
						queryOperatorCmdByNet(phoneNum, simIccid, extend,callBack);
					}
				
				}else{
					// 没过期
					XyUtil.doXycallBackResult(callBack, "0", retActionJson);
					return retActionJson;
				}
			    /*HWWATCH-4 songzhirong 20160818 end*/

			} catch (Throwable e) {
	            LogManager.e(Constant.TAG, "queryOperatorCmd: ", e);
			}
		}else{
    		//没数据
			int netType = XyUtil.checkNetWork(Constant.getContext());
			if (netType == -1) {// 没可用网络
                XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "have no available net work");
			} else {
				queryOperatorCmdByNet(phoneNum, simIccid, extend, callBack);
			}
    	}
		return null;
    }
    
    private static void queryOperatorCmdByNet(final String phoneNum, final String simIccid,final HashMap<String,String> extend, final SdkCallBack callBack){
        /* SDK-529 huangzhiqiang 20160711 start */
        if (StringUtils.isNull(phoneNum)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "phone num is null");
            return;
        }
        /* SDK-529 huangzhiqiang 20160711 end */

        final String dataString = ServerUtil.QueryOperatorRequest(phoneNum, simIccid, extend);
        if (StringUtils.isNull(dataString)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "request content error");
            return;
        }

        NetUtil.requestNewTokenIfNeed(extend);
        /* SDK-526 huangzhiqiang 20160708 start */
        final String token = NetUtil.getToken();
        /* SDK-526 huangzhiqiang 20160708 end */

         SdkCallBack netSdkCallBack = new SdkCallBack(){
			@Override
			public void execute(Object... obj) {
				if (obj != null && obj.length > 0) {
					String resutCode = obj[0].toString();
					if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
                        /* SDK-526 huangzhiqiang 20160708 start */
                        NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.REQ_QUERY_OPERATOR, dataString,
                                Constant.FIVE_MINUTES, isNewThread(extend), false, true, extend, token, this);
                        return;
                        /* SDK-526 huangzhiqiang 20160708 end */
					}

					if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_PARE_ERR)
							|| resutCode.equals(NewXyHttpRunnable.ERROR_CODE_SERVICE_ERR)) {
						// 网络失败
						XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "server error");
					} else {
						if (resutCode.equals("0") && obj.length == 2) {
							String response = obj[1].toString();
							OperatorCmdManager.insertOrUpdateOperatorCmd(phoneNum, simIccid, response);
							try {
								JSONObject jsonObject = new JSONObject(response);
								XyUtil.doXycallBackResult(callBack, "0",jsonObject);
							} catch (Throwable e) {
								// 网络失败
								XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "response content error");
							}
						} else { // 网络失败
							XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "response code wrong, code=" + resutCode);
						}
					}
				} else { // 网络失败
					XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "no result");
				}
			}
         };
        try {
            NetUtil.executeNewServiceHttpRequest(NetUtil.REQ_QUERY_OPERATOR, dataString, netSdkCallBack,
                    isNewThread(extend), false, true, extend);
        } catch (Throwable e) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "request error:" + e.getMessage());
        }
    }

    private static void queryOperatorMsgByNet(final String phoneNum, final String msg,final HashMap<String,String> extend, final SdkCallBack callBack){
        /* SDK-529 huangzhiqiang 20160711 start */
        if (!StringUtils.allValuesIsNotNull(phoneNum, msg)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "phone num or sms content is null");
            return;
        }
        /* SDK-529 huangzhiqiang 20160711 end */
        final String dataString = ServerUtil.QueryOperatorMsgRequest(phoneNum, msg, extend);
        if (StringUtils.isNull(dataString)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "request content error");
            return;
        }

        NetUtil.requestNewTokenIfNeed(extend);
        /* SDK-526 huangzhiqiang 20160708 start */
        final String token = NetUtil.getToken();
        /* SDK-526 huangzhiqiang 20160708 end */

        SdkCallBack netSdkCallBack = new SdkCallBack(){

			@Override
			public void execute(Object... obj) {
				if (obj != null && obj.length > 0) {
					String resutCode = obj[0].toString();
					if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
                        /* SDK-526 huangzhiqiang 20160708 start */
                        NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.REQ_QUERY_OPERATOR_MSG, dataString,
                                Constant.FIVE_MINUTES, isNewThread(extend), false, true, extend, token, this);
                        return;
                        /* SDK-526 huangzhiqiang 20160708 end */
					} 

					if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_PARE_ERR)
							|| resutCode.equals(NewXyHttpRunnable.ERROR_CODE_SERVICE_ERR)) {
						// 网络失败
						XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "server error");
					} else {
						if (resutCode.equals("0") && obj.length == 2) {
							String response = obj[1].toString();
							OperatorParseManager.insertOrUpdateOperatorMsg(phoneNum, msg, response);
							try {
								JSONObject jsonObject = new JSONObject(response);
								XyUtil.doXycallBackResult(callBack, "0", jsonObject);
							} catch (Throwable e) {
								// 网络失败
								XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "response content error");
							}
						} else { // 网络失败
						    XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "response code wrong, code=" + resutCode);
						}
					}

				} else { // 网络失败
				    XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "no result");
				}
			}
       	 
        };
        try {
            NetUtil.executeNewServiceHttpRequest(NetUtil.REQ_QUERY_OPERATOR_MSG, dataString, netSdkCallBack,
                    isNewThread(extend), false, true, extend);
        } catch (Throwable e) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "request error:" + e.getMessage());
        }
   }
    
    private static boolean isNewThread(Map extend){
		 if(extend==null)return true;
		 if(!extend.containsKey("isNewThread")) return true;
		 String isNewThread = (String)extend.get("isNewThread");
		 return "true".equalsIgnoreCase(isNewThread);
	 }

    public static JSONObject queryOperatorMsg(String phoneNum, String msg,
    		 HashMap<String, String> extend, SdkCallBack callBack) {
        /* SDK-529 huangzhiqiang 20160711 start */
        if (!StringUtils.allValuesIsNotNull(phoneNum, msg)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "phone num or sms content is null");
            return null;
        }
        /* SDK-529 huangzhiqiang 20160711 end */
        // 先查本地缓存，
        // 本地缓存是否过有效期，过有效期需要重新网络查询。
        // 网络查询到，持久化到缓存。    	
    	JSONObject json = OperatorParseManager.queryOperatorMsg(phoneNum, msg, extend);
    	if(json!=null){
			try {
				String time = json.optString(OperatorParseManager.UPDATE_INFO_TIME);
			    /*HWWATCH-4 songzhirong 20160818 start*/
				String resultStr = json.optString(OperatorParseManager.RESULT);
				
				JSONObject retActionJson = new JSONObject(resultStr);
				long updateTime = Long.parseLong(time);
				
				if((Constant.EMPTY_JSON.equals(resultStr) && System.currentTimeMillis() > updateTime + Constant.HOUR * 6)
						|| (System.currentTimeMillis() > (updateTime + DexUtil
								.getUpdateCycleByType(OnlineUpdateCycleConfigInterface.TYPE_QUERY_OPERATOR_MSG_INFO_CYCLE,Constant.month)))){
					// 已过期
					int netType = XyUtil.checkNetWork(Constant.getContext());
					if (netType == -1) {// 无可用网络，因为无法查询，就返回之前的数据
						XyUtil.doXycallBackResult(callBack, "0", retActionJson);
						return retActionJson;
					} else {
						queryOperatorMsgByNet(phoneNum, msg, extend, callBack);
					}				
				}else{
					// 没过期
					XyUtil.doXycallBackResult(callBack, "0", retActionJson);
					return retActionJson;
				}	
			    /*HWWATCH-4 songzhirong 20160818 end*/

			} catch (Throwable e) {
				XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "error:" + e.getMessage());
			}
    	}else{
    		//没数据
    		  int netType = XyUtil.checkNetWork(Constant.getContext());
	          if (netType == -1)
	          {//没可用网络
	        	  XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "have no available net work");
	          }
	          else{
	        	  queryOperatorMsgByNet(phoneNum, msg, extend, callBack);
	          }
    	}
    	
        return null;
    }

    public static JSONObject parseOperatorMsg(Context ctx, String msgId, String smsReceiveNum, String smsCenterNum,
            String smsContent, long smsTime, HashMap<String, String> extend, SdkCallBack callBack) {
        /* SDK-529 huangzhiqiang 20160711 start */
        if (!StringUtils.allValuesIsNotNull(smsReceiveNum, smsContent)) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, "phone num or sms content is null");
            return null;
        }
        /* SDK-529 huangzhiqiang 20160711 end */
        return queryOperatorMsg(smsReceiveNum, smsContent, extend, callBack);
    }
}
